2

项目:laravel + vue 实现前后端分离。
vue-router 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。

  • hash URL 例如:http://yoursite.com/#/user/id
  • history 模式时,URL就像正常的 url,例如 http://yoursite.com/user/id

没有特别的要求的话,hash模式亦正常访问。好嘛,产品要求URL要像正常那样的 —— history模式的。看看vue文档,要实现vue history模式也很简单。vue 切换一下模式,本地测试ok啦。
接下来,看到还需要后台配置支持:

因为VUE应用是个单页客户端应用,如果后台没有正确的配置,当用户在浏览器直接访问 http://oursite.com/user/id 就会返回 404,这就不好看了。所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。

So,Nginx配置一下:

location / {
  try_files $uri $uri/ /index.html;
}

没错,部署前端资源Nginx服务器上,简单加上一条通用匹配规则。
至此,vue 前端搞定了,但是。。。还是不行的!
原因是从前端服务器访问是正常了,但是域名指向的是后端服务器,所以当vue router history模式url直接访问时还是会404.
当到这里,又回头排查一下是不是前面哪里搞错了,仔细看下来,没问题啊,完全按vue文档说明操作啦。
想一阵子,才找到思路:404是后端报出的,也就说Laravel给出的,laravel router 压根就没前端定义的路由。所以,当即一拍脑子,就想到是不是将laravel 异常处理在response出去前给中断一下,将404处理交给前端再处理一下,那么也只是需要在app/Exceptions/Handlerrender方法加下判断:

/**
     * Render an exception into an HTTP response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Exception  $exception
     * @return \Illuminate\Http\Response
     */
    public function render($request, Exception $exception)
    {
        // 解决vue history 地址丢失问题
        if($exception instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException)
        {
            if ($exception->getStatusCode() == 404) {
                return response()->view('welcome');
            }
        }
        return parent::render($request, $exception);
    }

解释一下:welcome 就是加载了vue CSS和JS,也就是vue依赖文件。
以上搞定前后端分离,vue history 404 问题!


Jess
10 声望1 粉丝

日拱一卒,不期速成